// 单件设计模式
// 构建单件设计模式【懒汉式单件设计模式 延迟使用】
// 第一步：把构造器设置为私有的，不允许外部来创建类的实例【对象】
// 第二步：至少应该提供一个外部访问的方法或属性，外部可以通过这个方法或属性来得到一个对象，
//        所以应该把这个方法设置为静态方法
// 第三步：外部调用第二步提供的静态方法来获取一个对象
export default class MyLocalStorage {
  // 对象属性【对象的基本类型属性和对象的引用属性】
  // 静态属性【静态的基本类型属性和静态的引用属性】
  static localStorage1: MyLocalStorage = new MyLocalStorage(); // 饿汉式单件设计模式
  count3!: number;
  // localStorage!: MyLocalStorage; // 忽略TS校验，不用赋予初始值
  static localStorage: MyLocalStorage; // 静态的属性就不用赋予初始值了，也不用!
  static count: number = 3; // 静态的基本类型属性
  private constructor(){
    console.log('这是TS的单件设计模式的静态方法的构造器');
  }

  // 提供一个外部访问的方法
  // 通过这个方法用来提供外部得到一个对象的方法

  // 1. 带 static 关键字的方法就是一个静态方法
  // 2. 静态方法和对象无关，外部的对象变量不能调用静态方法和静态属性
  // 3. 外部可以通过类名来调用
  // 注意：在静态的方法里面是可以调用静态的其它成员【不可以访问实例属性和实例方法】，包括：静态的方法和静态的属性
  public static getInstance(){
    // let localStorage = new MyLocalStorage(); // 这样会创建多个实例
    // return localStorage;
    // return new MyLocalStorage();
    // 使用局部变量来解决 失败了
    /*let localStorage;
    if(!localStorage){
      localStorage = new MyLocalStorage();
    }
    return localStorage; */
    // 静态属性在静态方法中也是可以通过 this 来访问的【静态方法不能调用对象属性, this.count3 是调用不到的】
    if(!this.localStorage){
      console.log('我是一个undefined的静态属性，用来指向一个对象空间的静态属性');
      this.localStorage = new MyLocalStorage(); // 私有的构造方法它不会禁止你在内部去调用构造方法
    }
    return this.localStorage;
  }

  // 保存key-value
  public setItem(key: string, value: any) {
    localStorage.setItem(key, JSON.stringify(value));
  }

  public getItem(key: string) {
    let value = localStorage.getItem(key);
    return value != null ? JSON.parse(value) : null;
  }
}
